package com.sw.code4j.common;

import java.util.HashSet;
import java.util.Set;

/**
 * @author: 张上亚 2021/11/30 13:36
 * @desc: 列类型转换工具类
 */
public class ColumnTypeUtils {

    public static Set<String> textType;
    public static Set<String> numberType;
    public static Set<String> timeType;

    static {
        textType = new HashSet<>();
        numberType = new HashSet<>();
        timeType = new HashSet<>();
        initDmColumnType(textType, numberType, timeType);
        initOracleColumnType(textType, numberType, timeType);
        initHiveColumnType(textType, numberType, timeType);
        initMysqlColumnType(textType, numberType, timeType);
        initKingbaseColumnType(textType, numberType, timeType);
    }






    /**
     * 根据数据库中列类型转为java中的字段类型
     *
     * @param columnType 列数据库类型
     * @return
     */
    public static String getJavaType(String columnType) {
        String upperCase = columnType.toUpperCase();
        if (textType.contains(upperCase)) {
            return JavaTypeEnum.STRING.getCode();
        } else if (timeType.contains(upperCase)) {
            return JavaTypeEnum.TIME.getCode();
        } else if (numberType.contains(upperCase)) {
            return JavaTypeEnum.NUMBER.getCode();
        } else {
            return JavaTypeEnum.STRING.getCode();
        }
    }


    private static void initDmColumnType(Set<String> textType, Set<String> numberType, Set<String> timeType) {
        textType.add("CHAR");
        textType.add("CHARACTER");
        textType.add("INTERVAL YEAR");
        textType.add("INTERVAL YEAR TO MONTH");
        textType.add("INTERVAL MONTH");
        textType.add("INTERVAL DAY");
        textType.add("VARCHAR");
        textType.add("INTERVAL DAY TO HOUR");
        textType.add("INTERVAL DAY TO MINUTE");
        textType.add("INTERVAL DAY TO SECOND");
        textType.add("INTERVAL HOUR");
        textType.add("INTERVAL HOUR TO MINUTE");
        textType.add("INTERVAL HOUR TO SECOND");
        textType.add("INTERVAL MINUTE");
        textType.add("INTERVAL MINUTE TO SECOND");
        textType.add("INTERVAL SECOND");
        textType.add("TEXT");
        textType.add("VARCHAR2");
        textType.add("LONGVARCHAR");
        textType.add("IMAGE");
        textType.add("LONGVARBINARY");
        textType.add("BLOB");
        textType.add("CLOB");
        textType.add("BFILE");
        textType.add("BINARY");
        textType.add("VARBINARY");

        numberType.add("INT");
        numberType.add("BIGINT");
        numberType.add("TINYINT");
        numberType.add("BYTE");
        numberType.add("BIT");
        numberType.add("SMALLINT");
        numberType.add("FLOAT");
        numberType.add("DOUBLE");
        numberType.add("REAL");
        numberType.add("DOUBLE PERCISION");
        numberType.add("NUMERIC");
        numberType.add("DECIMAL");
        numberType.add("NUMBER");
        numberType.add("DOUBLE PRECISION");
        numberType.add("DEC");
        numberType.add("INTEGER");

        timeType.add("DATE");
        timeType.add("TIME");
        timeType.add("TIMESTAMP");
        timeType.add("DATETIME");
        timeType.add("TIME WITH TIME ZONE");
        timeType.add("TIMESTAMP WITH LOCAL TIME ZONE");
    }

    private static void initKingbaseColumnType(Set<String> textType, Set<String> numberType, Set<String> timeType) {

        textType.add("BOOLEAN");
        textType.add("BLOB");
        textType.add("CHARACTER");
        textType.add("CHARACTER VARYING");
        textType.add("CLOB");
        textType.add("NVARCHAR");
        textType.add("NVARCHAR2");
        textType.add("TEXT");
        textType.add("VARCHAR2");
        textType.add("XML");

        numberType.add("BIGINT");
        numberType.add("BIGSERIAL");
        numberType.add("DECIMAL");
        numberType.add("DOUBLE");
        numberType.add("DOUBLE PRECISION");
        numberType.add("INTEGER");
        numberType.add("INTERVAL");
        numberType.add("NUMBER");
        numberType.add("NUMERIC");
        numberType.add("SMALLINT");
        numberType.add("TINYINT");
        numberType.add("REAL");
        numberType.add("SERIAL");
        numberType.add("SMALLSERIAL");

        timeType.add("DATE");
        timeType.add("TIME");
        timeType.add("TIME WITH TIME ZONE");
        timeType.add("TIMESTAMP");
        timeType.add("TIMESTAMP WITH TIME ZONE");
    }

    private static void initMysqlColumnType(Set<String> textType, Set<String> numberType, Set<String> timeType) {
        textType.add("CHAR");
        textType.add("VARCHAR");
        textType.add("TINYTEXT");
        textType.add("TEXT");
        textType.add("MEDIUMTEXT");
        textType.add("LONGTEXT");
        textType.add("BLOB");

        numberType.add("TINYINT");
        numberType.add("SMALLINT");
        numberType.add("MEDIUMINT");
        numberType.add("INT");
        numberType.add("BIGINT");
        numberType.add("FLOAT");
        numberType.add("DOUBLE");
        numberType.add("DECIMAL");

        timeType.add("DATE");
        timeType.add("TIME");
        timeType.add("DATETIME");
        timeType.add("TIMESTAMP");
    }

    private static void initHiveColumnType(Set<String> textType, Set<String> numberType, Set<String> timeType) {
        textType.add("CHAR");
        textType.add("VARCHAR");
        textType.add("STRING");

        numberType.add("DECIMAL");
        numberType.add("INT");
        numberType.add("BIGINT");
        numberType.add("TINYINT");
        numberType.add("SMALLINT");
        numberType.add("FLOAT");
        numberType.add("DOUBLE");
        numberType.add("DOUBLE PRECISION");

        timeType.add("DATE");
        timeType.add("TIMESTAMP");
    }

    private static void initOracleColumnType(Set<String> textType, Set<String> numberType, Set<String> timeType) {
        textType.add("CHAR");
        textType.add("VARCHAR2");
        textType.add("NVARCHAR2");
        textType.add("LONG");
        textType.add("LONG RAW");
        textType.add("BLOB");
        textType.add("CLOB");
        textType.add("NCLOB");
        textType.add("RAW");

        numberType.add("DOUBLE PRECISION");
        numberType.add("NUMBER");
        numberType.add("INTEGER");
        numberType.add("BINARY_FLOAT");
        numberType.add("BINARY_DOUBLE");

        timeType.add("DATE");
        timeType.add("TIMESTAMP");
        timeType.add("TIMESTAMP WITH TIME ZONE");
        timeType.add("TIMESTAMP WITH LOCAL TIME ZONE");
    }
}
